在 Web API 中看到 Observer 單字的,多半都跟監聽、觀察有關,今天要介紹的 Mutation Observer API 就是其中一樣,他可以監聽 DOM 的變化。當我們需要即時更新,或動態監聽 DOM 時,使用 Mutation Observer API,就不要輪詢或反覆查詢 DOM,所以能提升響應的速度與效能。
常應用的情境包括但不限:
監聽 DOM 的變動可以拆解成以下幾個步驟:
MutationObserver
實例,當監聽的 DOM 變動時,會調用 callback 函式observe
方法開始監聽disconnect
停止監聽程式碼範例如下:
// 指定想要監聽的 DOM 節點
const targetNode = document.getElementById('myElement');
// 定義觀察選項
const config = {
attributes: true, // 監聽屬性變更
childList: true, // 監聽子節點變動
characterData: true, // 監聽文本內容改變
subtree: true // 監聽所有子節點的變動
};
const callback = (mutationsList) => {
mutationsList.forEach((mutation) => {
console.log('Mutation type:', mutation.type);
if (mutation.type === 'attributes') {
console.log('Attribute changed:', mutation.attributeName);
} else if (mutation.type === 'childList') {
console.log('Child nodes changed:', mutation);
} else if (mutation.type === 'characterData') {
console.log('Text content changed:', mutation.target.data);
}
});
};
// 建立 MutationObserver 實例,並傳入 callback 函式
const observer = new MutationObserver(callback);
// 開始觀察
observer.observe(targetNode, config);
// 停止觀察
observer.disconnect();
接著進一步分享我們可以監聽的種類
attributes
)如果一個元素的 class
或 id
被修改,MutationObserver
就會捕捉到這個變動。在觀察選項中將 attributes
設置為 true
,即可啟用這種類型的監聽。
範例:
const config = { attributes: true };
如果只想監聽特定屬性的變動,可以通過 attributeFilter
選項指定:
const config = {
attributes: true,
attributeFilter: ['class', 'id'] // 只監聽 class 和 id 屬性
};
childList
)用於監聽新增或刪除元素子節點的變動。如果 DOM 中有元素被插入或移除,MutationObserver
就能捕捉到這個變動。將 childList
設置為 true
,即可啟用這種類型的監聽。
範例:
const config = { childList: true };
如果想監聽所有後代節點的變動,可以將 subtree
設為 true
:
const config = {
childList: true,
subtree: true // 監聽所有後代節點的變動
};
characterData
)當我們修改元素中的文字時,就會觸發這個監聽,將 characterData
設置為 true
以使用。
範例:
const config = { characterData: true };
同樣,如果需要監聽所有後代節點的文字內容變動,也可以設置 subtree
為 true
:
const config = {
characterData: true,
subtree: true // 監聽所有後代節點的文字變動
};
MutationObserver API 提供了一個高效的方法來監聽 DOM 的變化,尤其是在需要即時響應變更的動態應用中。我們可以不用依賴傳統的監聽方式,取而代之的,是使用更靈活的 MutationObserver API 來追蹤特定元素的變動。若有在考慮如何提升網頁效能,MutationObserver API 會是一個值得嘗試的工具。
以上有任何問題,歡迎留言討論。